package per.turtle.system.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import per.turtle.common.core.utils.SecurityUtils;
import per.turtle.common.core.web.controller.BaseController;
import per.turtle.common.core.web.entity.CommonResult;
import per.turtle.common.core.web.page.TableDataInfo;
import per.turtle.common.excel.annotation.RequestExcel;
import per.turtle.common.excel.annotation.ResponseExcel;
import per.turtle.common.excel.annotation.Sheet;
import per.turtle.common.log.annotation.Log;
import per.turtle.common.log.enums.BusinessType;
import per.turtle.common.security.annotation.OnlyInterService;
import per.turtle.common.security.annotation.PreAuthorize;
import per.turtle.system.dto.LoginUser;
import per.turtle.system.entity.SysRole;
import per.turtle.system.entity.SysUser;
import per.turtle.system.service.*;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author turtle
 */
@RequestMapping("user")
@RequiredArgsConstructor
@RestController
@Tag(name = "用户管理", description = "user_用户管理模块")
public class SysUserController extends BaseController {

    private final ISysUserService userService;

    private final ISysRoleService roleService;

    private final ISysPostService postService;

    private final ISysDeptService deptService;

    private final ISysPermissionService permissionService;

    @Operation(summary = "新增用户", description = "新增用户")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping
    @PreAuthorize(hasPermission = "system:user:add")
    public CommonResult<Void> add(@Validated @RequestBody SysUser user) {
        if (!userService.checkUserNameUnique(user)) {
            return CommonResult.error("新增用户【" + user.getUserName() + "】失败，登录账号已存在");
        } else if (StrUtil.isNotEmpty(user.getPhoneNumber()) && !userService.checkPhoneUnique(user)) {
            return CommonResult.error("新增用户【" + user.getUserName() + "】失败，手机号码已存在");
        } else if (StrUtil.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
            return CommonResult.error("新增用户【" + user.getUserName() + "】失败，邮箱账号已存在");
        }
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        return result(userService.insertUser(user));
    }

    @Operation(summary = "状态修改", description = "状态修改")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PreAuthorize(hasPermission = "system:user:edit")
    @PutMapping("changeStatus")
    public CommonResult<Void> changeStatus(@RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        return result(userService.updateUserStatus(user));
    }

    @Operation(summary = "修改用户", description = "修改用户")
    @PreAuthorize(hasPermission = "system:user:edit")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public CommonResult<Void> edit(@Validated @RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        if (StrUtil.isNotEmpty(user.getPhoneNumber()) && !userService.checkPhoneUnique(user)) {
            return CommonResult.error("修改用户【" + user.getUserName() + "】失败，手机号码已存在");
        } else if (StrUtil.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
            return CommonResult.error("修改用户【" + user.getUserName() + "】失败，邮箱账号已存在");
        }
        return result(userService.updateUser(user));
    }

    @Operation(summary = "导出用户数据", description = "导出用户数据")
    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @PostMapping("export")
    @PreAuthorize(hasPermission = "system:user:export")
    @ResponseExcel(name = "用户", sheets = @Sheet(sheetName = "用户"))
    public List<SysUser> export(HttpServletResponse response, @RequestBody SysUser user) {
        return userService.selectUserList(user);
    }

    @Operation(summary = "获取用户信息", description = "获取用户信息")
    @GetMapping("getInfo")
    public CommonResult<SysUser> getInfo() {
        String userId = SecurityUtils.getUserId();
        SysUser user = userService.selectUserById(userId);
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(userId);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(userId);

        Map<String, Set<String>> map = new HashMap<>(2);
        map.put("roles", roles);
        map.put("permissions", permissions);
        return CommonResult.success(user).setMap(map);
    }

    @Operation(summary = "根据用户编号获取详细信息", description = "根据用户编号获取详细信息")
    @GetMapping({"/", "/{userId}"})
    @PreAuthorize(hasPermission = "system:user:query")
    public CommonResult<SysUser> getInfo(@PathVariable(value = "userId", required = false) String userId) {
        SysUser user = new SysUser();
        List<SysRole> roles = roleService.selectRoleAll();
        user.setRoles(SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        user.setPosts(postService.selectPostAll());
        if (StrUtil.isNotBlank(userId)) {
            BeanUtil.copyProperties(userService.selectUserById(userId), user);
            user.setRoleIds(user.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
            user.setPostIds(postService.selectPostListByUserId(userId));
        }

        return CommonResult.success(user);
    }

    @Operation(summary = "根据用户编号获取授权角色", description = "根据用户编号获取授权角色")
    @GetMapping("getUserRoles/{userId}")
    @PreAuthorize(hasPermission = "system:user:query")
    public CommonResult<SysUser> getUserRoles(@PathVariable("userId") String userId) {
        SysUser user = userService.selectUserById(userId);
        user.setRoles(roleService.selectRolesByUserId(userId));
        return CommonResult.success(user);
    }

    @Operation(summary = "导入用户数据", description = "导入用户数据")
    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @PostMapping("importData")
    @PreAuthorize(hasPermission = "system:user:import")
    public CommonResult<?> importData(@RequestExcel List<SysUser> userList, boolean updateSupport) {
        for (SysUser user : userList) {
            if (!userService.checkUserNameUnique(user)) {
                return CommonResult.error("用户【" + user.getUserName() + "】，账号已存在");
            } else if (StrUtil.isNotEmpty(user.getPhoneNumber()) && !userService.checkPhoneUnique(user)) {
                return CommonResult.error("用户【" + user.getUserName() + "】，手机号码已存在");
            } else if (StrUtil.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
                return CommonResult.error("用户【" + user.getUserName() + "】，邮箱账号已存在");
            }
            user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        }
        return CommonResult.success(userService.saveBatch(userList));
    }

    @Operation(summary = "下载导入模板", description = "下载导入模板")
    @PostMapping("importTemplate")
    @ResponseExcel("模板")
    public List<SysUser> importTemplate(HttpServletResponse response) {
        return null;
    }

    @Operation(summary = "获取当前用户信息", description = "获取当前用户信息")
    @GetMapping("info/{username}")
    @OnlyInterService
    public CommonResult<LoginUser> info(@PathVariable("username") String username) {
        SysUser sysUser = userService.selectUserByUserName(username);
        LoginUser loginUser = null;
        if (!BeanUtil.isEmpty(sysUser)) {
            loginUser = new LoginUser();
            // 角色集合
            loginUser.setRoles(permissionService.getRolePermission(sysUser.getUserId()));
            // 权限集合
            loginUser.setPermissions(permissionService.getMenuPermission(sysUser.getUserId()));
            loginUser.setSysUser(sysUser);
        }
        return CommonResult.success(loginUser);
    }

    @Operation(summary = "用户授权角色", description = "用户授权角色")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PreAuthorize(hasPermission = "system:user:edit")
    @PutMapping("authRole")
    public CommonResult<Void> insertAuthRole(String userId, String[] roleIds) {
        userService.insertUserAuth(userId, roleIds);
        return CommonResult.success();
    }

    @Operation(summary = "获取用户列表或分页", description = "获取用户列表或分页（区别于是否传入分页参数）")
    @PostMapping("list")
    @PreAuthorize(hasPermission = "system:user:list")
    public TableDataInfo<SysUser> list(@RequestBody SysUser user) {
        List<SysUser> list = startPage(s -> userService.selectUserList(user));
        list.forEach(sysUser -> {
            sysUser.setDeptName(deptService.getDeptById(sysUser.getDeptId()).getDeptName());
        });
        return getDataTable(list);
    }

    @Operation(summary = "删除用户", description = "删除用户")
    @DeleteMapping("{userIds}")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @PreAuthorize(hasPermission = "system:user:remove")
    public CommonResult<Void> remove(@PathVariable List<String> userIds) {
        return result(userService.deleteUserByIds(userIds));
    }

    @Operation(summary = "重置密码", description = "重置密码")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PreAuthorize(hasPermission = "system:user:edit")
    @PutMapping("resetPwd")
    public CommonResult<Void> resetPwd(@RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        return result(userService.resetPwd(user));
    }

}
